module Kata {
    export class FizzBuzz {
        private numberProcessorChain: INumberToText;

        constructor() {
            this.numberProcessorChain =
                new Number(
                    new Whizz(
                        new Buzz(
                            new Fizz())));
        }

        getOutput(num: number): string {
            var output = this.numberProcessorChain.getText(num);
            return output;
        }
    }

    interface INumberToText {
        getText(num: number): string;
    }

    class Fizz implements INumberToText {
        getText(num: number): string {
            if (num % 3 === 0) {
                return 'Fizz';
            }

            return '';
        }
    }

    class Buzz {
        constructor(private numberToText: INumberToText) { }

        getText(num: number): string {
            var output = this.numberToText.getText(num);

            if (num % 5 === 0) {
                output += 'Buzz';
            }

            return output;
        }
    }

    class Whizz {
        constructor(private numberToText: INumberToText) { }

        getText(num: number): string {
            var output = this.numberToText.getText(num);

            if (num % 7 === 0) {
                output += 'Whizz';
            }

            return output;
        }
    }

    class Number {
        constructor(private numberToText: INumberToText) { }

        getText(num: number): string {
            var output = this.numberToText.getText(num);

            if (output === '') {
                output = num.toString();
            }

            return output;
        }
    }
}